﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Windows;
using System.Xml.Serialization;

namespace BDSim
{
    /// <summary>
    /// 卫星轨道位置速度结构体
    /// </summary>
    [StructLayout(LayoutKind.Sequential), TypeConverter(typeof(ExpandableObjectConverter))]
    public struct NodePosVel
    {
        /// <summary>
        /// 轨道历元
        /// </summary>
        [XmlIgnore]
        public UTCTime epoch;

        [XmlIgnore]
        public double x;

        [XmlIgnore]
        public double y;

        [XmlIgnore]
        public double z;

        [XmlIgnore]
        public double vx;

        [XmlIgnore]
        public double vy;

        [XmlIgnore]
        public double vz;

        [XmlAttribute]
        public double X { get { return x; } set { x = value; } }

        [XmlAttribute]
        public double Y { get { return y; } set { y = value; } }

        [XmlAttribute]
        public double Z { get { return z; } set { z = value; } }

        [XmlAttribute]
        public double VX { get { return vx; } set { vx = value; } }

        [XmlAttribute]
        public double VY { get { return vy; } set { vy = value; } }

        [XmlAttribute]
        public double VZ { get { return vz; } set { vz = value; } }

        public UTCTime Epoch { get { return epoch; } set { epoch = value; } }

        public NodePosVel(UTCTime e, double Px, double Py, double Pz, double Vx, double Vy, double Vz)
        {
            epoch = e;
            x = Px;
            y = Py;
            z = Pz;
            vx = Vx;
            vy = Vy;
            vz = Vz;
        }

        public NodePosVel(UTCTime e)
        {
            epoch = e;
            x = y = z = vx = vy = vz = 0;
        }

        public NodePosVel(double Px, double Py, double Pz, double Vx, double Vy, double Vz)
        {
            epoch = new UTCTime();
            x = Px;
            y = Py;
            z = Pz;
            vx = Vx;
            vy = Vy;
            vz = Vz;
        }
    };

    public enum EConstellationType
    {
        /// <summary>
        /// 北斗星座
        /// </summary>
        BDS,
        /// <summary>
        /// GPS星座
        /// </summary>
        GPS,
        /// <summary>
        /// 格洛纳斯星座
        /// </summary>
        GLONASS,
        /// <summary>
        /// 伽利略星座
        /// </summary>
        Galileo
    }

    /// <summary>
    /// 卫星轨道结构体
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct OrbitSixElement
    {
        /// <summary>
        /// UTC形式的轨道历元
        /// </summary>
        public UTCTime t;

        /// <summary>
        /// 轨道椭圆的长半轴
        /// </summary>
        public double a;

        /// <summary>
        /// 轨道椭圆的偏心率
        /// </summary>
        public double e;

        /// <summary>
        /// 升交点的赤经
        /// </summary>
        public double O;

        /// <summary>
        /// 轨道面的倾角
        /// </summary>
        public double i;

        /// <summary>
        /// 近地点角距 
        /// </summary>
        public double w;

        /// <summary>
        /// 卫星的偏近点角
        /// </summary>
        public double E;

        /// <summary>
        /// 卫星的平近点角
        /// </summary>
        public double M;

        /// <summary>
        /// 卫星的真近点角 
        /// </summary>
        public double f;

        /// <summary>
        /// 卫星的升交距角
        /// </summary>
        public double u;

        /// <summary>
        /// 平均轨道角速度
        /// </summary>
        public double n;

        /// <summary>
        /// 卫星经过近地点时间
        /// </summary>
        public double t0;

        /// <summary>
        /// 卫星的初始平近点角
        /// </summary>
        public double M0;
    };

    /// <summary>
    /// 星历16参
    /// </summary>
    public struct SixTeen_Ephemeris
    {
        /// <summary>
        /// toe对应的UTC时间
        /// </summary>
        public UTCTime t;
        public double toe;
        public double sqrtA;
        public double e;
        public double i;
        public double Omega0;
        public double w;
        public double M;
        public double deltaN;
        public double OmegaDot;
        public double idot;
        public double Crs;
        public double Crc;
        public double Cus;
        public double Cuc;
        public double Cis;
        public double Cic;

        public SixTeen_Ephemeris(UTCTime pt, double ptoe, double psqrtA, double pe, double pi, double pOmega0, double pw, double pM, double pdeltaN,
            double pOmegaDot, double pidot, double pCrs, double pCrc, double pCus, double pCuc, double pCis, double pCic)
        {
            t = pt;
            toe = ptoe;
            sqrtA = psqrtA;
            e = pe;
            i = pi;
            Omega0 = pOmega0;
            w = pw;
            M = pw;
            deltaN = pdeltaN;
            OmegaDot = pOmega0;
            idot = pidot;
            Crs = pCrs;
            Crc = pCrc;
            Cus = pCus;
            Cuc = pCuc;
            Cis = pCis;
            Cic = pCic;
        }
    };
  
    /// <summary>
    /// 轨道动力学配置参数类，用于界面设置
    /// </summary>
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class OrbitPredictParamClass
    {
        #region 字段

        /// <summary>
        /// 卫星等效横截面积；界面输入
        /// </summary>
        private double _SatArea;

        /// <summary>
        /// 卫星质量；界面输入
        /// </summary>
        private double _SatMass;

        /// <summary>
        /// 非球形摄动；界面输入
        /// </summary>
        private byte _NonSphPert;

        /// <summary>
        /// 引力场模型
        /// </summary>
        private EEarthPotentialModel _EarthPotentialModel;

        /// <summary>
        /// 引力场模型最高阶数；界面输入
        /// </summary>
        private int _EarthPotentialM;

        /// <summary>
        /// 引力场模型最高次数；界面输入
        /// </summary>
        private int _EarthPotentialN;

        /// <summary>
        /// 太阳引力摄动控制参数；界面输入
        /// </summary>
        private byte _SunPert;

        /// <summary>
        /// 月球引力摄动控制参数；界面输入
        /// </summary>
        private byte _MoonPert;
        
        /// <summary>
        /// 太阳光压摄动控制参数；界面输入
        /// </summary>
        private byte _SunSrpPert;

        /// <summary>
        /// 太阳光压模型选择0:3参数球模型；1:6参数模型；2:9参数模型；
        /// </summary>
        private int _SunSrpModel;

        /// <summary>
        /// 阴影模型选取标志，0-不考虑，1-柱形模型，2-椎形模型；界面输入
        /// </summary>
        private int _ShadModelTag;

        /// <summary>
        /// 太阳光压参数（9参）；界面输入
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
        private double[] _SunSrpParam;
        
        /// <summary>
        /// ROCK模型选择，1: ROCK T MODEL (T10, T20, T30)，2: ROCK S MODEL (S10, S20) ，8: CODE MODEL (9801) ， 9: JPL MODEL (GPS_XYZ)
        /// </summary>
        private int _ROCKM;
        
        /// <summary>
        /// BLOCK模型，1: BLOCK I， 2: BLOCK II，3: BLOCK IIA，4: BLOCK IIR，5: BLOCK IIF
        /// </summary>
        private int _BLOCK;

        /// <summary>
        /// ROCK模型参数
        /// </summary>
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
        private double[] _P02RAD;

        /// <summary>
        /// 固体潮汐摄动控制开关，0：不考虑；其他值，开关打开，考虑固体潮汐摄动
        /// </summary>
        private int _Tide;

        #endregion

        #region 属性
        
        /// <summary>
        ///卫星等效横截面积,单位(㎡) 
        /// </summary>
        public double SatArea
        {
            get { return _SatArea; }
            set
            {
                if (value >= 0)
                {
                    _SatArea = value;
                }
            }
        }

        /// <summary>
        /// 卫星质量,单位(kg)
        /// </summary>
        public double SatMass
        {
            get { return _SatMass; }
            set
            {
                if (value >= 0)
                {
                    _SatMass = value;
                }
            }
        }

        /// <summary>
        /// 非球形摄动
        /// </summary>
        public byte NonSphPert
        {
            get { return _NonSphPert; }
            set { _NonSphPert = value; }
        }

        /// <summary>
        /// 引力场模型
        /// </summary>
        public EEarthPotentialModel EarthPotentialModel
        {
            get { return _EarthPotentialModel; }
            set { _EarthPotentialModel = value; }
        }

        /// <summary>
        /// 引力场模型最高阶数
        /// </summary>
        public int EarthPotentialM
        {
            get { return _EarthPotentialM; }
            set
            {
                if (value < 0 || value > 10)
                {
                    MessageBox.Show("田谐项最高次数需设置在[0,10]之间!");
                }
                else if (value < _EarthPotentialN)
                {
                    MessageBox.Show("SphFiledM应大于等于SphFiledN");
                }
                else
                {
                    _EarthPotentialM = value;
                }
            }
        }

        /// <summary>
        /// 引力场模型最高次数
        /// </summary>
        public int EarthPotentialN
        {
            get { return _EarthPotentialN; }
            set
            {
                if (value > _EarthPotentialM)
                {
                    MessageBox.Show("SphFiledN应小于等于SphFiledM");
                }
                else
                {
                    _EarthPotentialN = value;
                }
            }
        }

        /// <summary>
        /// 太阳引力摄动控制参数
        /// </summary>
        public byte SunPert
        {
            get { return _SunPert; }
            set { _SunPert = value; }
        }

        /// <summary>
        /// 月球引力摄动控制参数
        /// </summary>
        public byte MoonPert
        {
            get { return _MoonPert; }
            set { _MoonPert = value; }
        }

        /// <summary>
        /// 太阳光压摄动控制参数
        /// </summary>
        public byte SunSrpPert
        {
            get { return _SunSrpPert; }
            set { _SunSrpPert = value; }
        }

        /// <summary>
        ///太阳光压模型选择0:3参数球模型；1:6参数模型；2:9参数模型 
        /// </summary>
        public int SunSrpModel
        {
            get { return _SunSrpModel; }
            set
            {
                if (value >= 0 && value <= 2)
                {
                    _SunSrpModel = value;
                }
            }
        }

        /// <summary>
        /// 阴影模型选取标志，0-不考虑，1-柱形模型，2-椎形模型
        /// </summary>
        public int ShadModelTag
        {
            get { return _ShadModelTag; }
            set
            {
                if (value >= 0 && value <= 2)
                {
                    _ShadModelTag = value;
                }
            }
        }

        /// <summary>
        /// 太阳光压参数（9参）
        /// </summary>
        public double[] SunRprParam
        {
            get { return _SunSrpParam; }
            set { _SunSrpParam = value; }
        }

        /// <summary>
        /// ROCK模型选择
        /// </summary>
        public int ROCKM
        {
            get { return _ROCKM; }
            set { _ROCKM = value; }
        }

        /// <summary>
        /// BLOCK模型选择
        /// </summary>
        public int BLOCK
        {
            get { return _BLOCK; }
            set { _BLOCK = value; }
        }

        /// <summary>
        /// ROCK模型参数
        /// </summary>
        public double[] P02RAD
        {
            get { return _P02RAD; }
            set { _P02RAD = value; }
        }

        /// <summary>
        /// 固体潮汐摄动控制开关，0：不考虑；其他值，开关打开，考虑固体潮汐摄动
        /// </summary>
        public int Tide
        {
            get { return _Tide; }
            set { _Tide = value; }
        }

        #endregion
    }

    public enum EEarthPotentialModel
    {
        JGM3,
        TEG4,
        EIGEN2
    }

    /// <summary>
    /// 积分器类型
    /// </summary>
    public enum EIntegratorType
    {
        RKF7,
        KSG
    }

    /// <summary>
    /// 积分器设置
    /// </summary> 
    public class IntegrationParamClass
    {
        #region 字段

        /// <summary>
        /// 积分器类型
        /// </summary>
        private EIntegratorType _Integration;

        /// <summary>
        /// 积分步长
        /// </summary>
        private int _StepSize;

        #endregion

        #region 属性

        public EIntegratorType Integration
        {
            get { return _Integration; }
            set { _Integration = value; }
        }

        public int StepSize
        {
            get { return _StepSize; }
            set { _StepSize = value; }
        }

        #endregion

    }

}
